﻿using PolePositionMobile.Entities;
using PolePositionMobile.Logic;
using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace PolePositionMobile
{
    /// <summary>
    /// A form that manages a visit's poles
    /// </summary>
    public partial class frmDataCollectionPole : frmBase
    {
        //Created by: VMCoder
        //Creation date: -
        //Last updated by: VMCoder
        //Last update: 2008.04.15

        #region Private Members
        private EVisit m_Visit;
        private bool m_TakePhotos;
        private List<Int32> m_SpeciesIdList;
        private List<Int32> m_ClassIdList;
        private List<Int32> m_TopIdList;
        private List<Int32> m_TreatmentIdList;
        private List<EPole> m_Poles;
        private double m_Latitude;
        private double m_Longitude;
        private double m_Altitude;
        private Int32 m_SatelliteCount;
        #endregion
        #region Public Properties
        public EVisit Visit
        {
            get { return m_Visit; }
            set { m_Visit = value; }
        }
        public bool TakePhotos
        {
            get { return m_TakePhotos; }
            set { m_TakePhotos = value; }
        }
        #endregion

        public frmDataCollectionPole()
        {
            InitializeComponent();
        }
        protected void frmDataCollectionPole_Load(object sender, EventArgs e)
        {
            #region Config form
            lblTitle.Text = "PPI | Transmission Locating";
            lblLButtonText.Text = "Menu";
            if (m_TakePhotos)
                lblRButtonText.Text = "Next";
            else
                lblRButtonText.Text = "Finish";
            lblLButton.ContextMenu = menLButton;
            LButtonMenuXOffset = 1;
            LButtonMenuYOffset = 116;
            tbcTabs.SelectedIndex = 1;
            tbcTabs.Visible = true;
            tbcTabs.Enabled = true;
            PolesNumber = m_Visit.Data != null && m_Visit.Data.Poles != null ? m_Visit.Data.Poles.Length : 0;
            PhotosNumber = m_Visit.Images != null ? m_Visit.Images.Length : 0;
            #endregion
            RefreshLocation();
            LoadCombos();
            if (m_Visit.Data != null && m_Visit.Data.Poles != null && m_Visit.Data.Poles.Length > 0)
                m_Poles = m_Visit.Data.Poles.ToList();
            else
                m_Poles = new List<EPole>();
            if (m_Visit.PolesToDelete == null)
                m_Visit.PolesToDelete = new List<Int32>();
            ShowList();
            Clear();
        }
        private void LoadCombos()
        {
            m_SpeciesIdList = Utils.FillLookupCombo(ddlSpecies, "Species", true);
            m_ClassIdList = Utils.FillLookupCombo(ddlClass, "Classes", true);
            Utils.FillNumericCombo(ddlLength, 30, 100, 5, true);
            Utils.FillNumericCombo(ddlYear, DateTime.Now.Year, DateTime.Now.Year - 100, 1, true);
            m_TopIdList = Utils.FillTopsCombo(ddlTop, m_Visit.VisitTypeFk, true);
            m_TreatmentIdList = Utils.FillLookupCombo(ddlTreatment, "Treatments", true, "Other");
            Utils.FillNumericCombo(ddlLVisit, DateTime.Now.Year, 1950, 1, true);
        }
        protected override void lblRButton_Click(object sender, EventArgs e)
        {
            if (m_Poles.Count > 0)
            {
                ShowLoading();
                Application.DoEvents();
                if (m_Visit.Data == null)
                    m_Visit.Data = new EData();
                m_Visit.Data.Poles = m_Poles.ToArray();
                if (m_TakePhotos)
                {
                    frmPhotos _Form = new frmPhotos();
                    _Form.Visit = m_Visit;
                    _Form.Settings = this.Settings;
                    _Form.Show();
                }
                else
                {
                    LogicLayer.SaveCompleteVisit(m_Visit,this.Settings);
                    frmHomePage _Form = new frmHomePage();
                    _Form.Settings = this.Settings;
                    _Form.Show();
                }
                this.Hide();
            }
            else
            {
                MessageBox.Show("There must be at least one pole in a visit", PPIConstants.K_AppName);
                tbcTabs.SelectedIndex = 1;
            }
        }

        private void mitCancel_Click(object sender, EventArgs e)
        {
            ShowLoading();
            Application.DoEvents();
            frmHomePage _Form = new frmHomePage();
            _Form.Settings = this.Settings;
            _Form.Show();
            this.Hide();
        }

        private void lstPoles_SelectedIndexChanged(object sender, EventArgs e)
        {
            mitDuplicatePole.Enabled = lstPoles.SelectedIndex > -1;
            mitDeletePole.Enabled = lstPoles.SelectedIndex > -1;
            if (lstPoles.SelectedIndex > -1)
            {
                EPole _Pole = m_Poles[lstPoles.SelectedIndex];

                ddlSpecies.SelectedIndex = m_SpeciesIdList.IndexOf(_Pole.SpeciesFk);
                ddlClass.SelectedIndex = m_ClassIdList.IndexOf(_Pole.ClassFk);
                ddlLength.SelectedIndex = _Pole.Length != double.MinValue ? ddlLength.Items.IndexOf(Convert.ToInt32(_Pole.Length)) : 0;
                ddlYear.SelectedIndex = _Pole.Year != Int32.MinValue ? ddlYear.Items.IndexOf(_Pole.Year) : 0;
                ddlTop.SelectedIndex = m_TopIdList.IndexOf(_Pole.TopTypeFk);
                ddlTreatment.SelectedIndex = m_TreatmentIdList.IndexOf(_Pole.TreatmentFk);
                txtLVisitor.Text = _Pole.LVisitor;
                ddlLVisit.SelectedIndex = _Pole.LVisit != Int32.MinValue ? ddlLVisit.Items.IndexOf(_Pole.LVisit) : 0;
                txtNumber.Text = _Pole.Number;
                if (_Pole.SolutionAvailable)
                {
                    m_Latitude = _Pole.Latitude;
                    m_Longitude = _Pole.Longitude;
                    m_Altitude = _Pole.Altitude;
                    m_SatelliteCount = _Pole.SatelliteCount;
                    lblLocation.Tag = true;
                    lblLocation.ForeColor = Color.Black;
                    lblLocation.Text = m_Latitude.ToString("F6") + " / " + m_Longitude.ToString("F6") + " / " + m_Altitude.ToString("F2") + "ft";
                }
                else
                {
                    m_Latitude = double.MinValue;
                    m_Longitude = double.MinValue;
                    m_Altitude = double.MinValue;
                    m_SatelliteCount = Int32.MinValue;
                    lblLocation.Tag = false;
                    lblLocation.ForeColor = Color.Red;
                    lblLocation.Text = "A GPS Solution is not available";
                }

                cmdAdd.Text = "Save";
            }
            else
                cmdAdd.Text = "Add";
        }

        private void cmdAdd_Click(object sender, EventArgs e)
        {
            SavePole();
        }
        private void SavePole()
        {
            SavePole(false);
        }
        private void SavePole(bool alwaysAdd)
        {
            DialogResult _DialogRes;
            string _ErrMsg = "";
            if (_ErrMsg != "")
                MessageBox.Show(_ErrMsg, PPIConstants.K_AppName);
            else
            {
                EPole _Pole = new EPole();
                _Pole.PoleId = lstPoles.SelectedIndex > -1 ? m_Poles[lstPoles.SelectedIndex].PoleId : Int32.MinValue;
                _Pole.SpeciesFk = m_SpeciesIdList[ddlSpecies.SelectedIndex];
                _Pole.ClassFk = m_ClassIdList[ddlClass.SelectedIndex];
                _Pole.Length = ddlLength.SelectedIndex != 0 ? double.Parse(ddlLength.Items[ddlLength.SelectedIndex].ToString()) : double.MinValue;
                _Pole.Year = ddlYear.SelectedIndex != 0 ? Int32.Parse(ddlYear.Items[ddlYear.SelectedIndex].ToString()) : Int32.MinValue;
                _Pole.TopTypeFk = m_TopIdList[ddlTop.SelectedIndex];
                _Pole.TreatmentFk = m_TreatmentIdList[ddlTreatment.SelectedIndex];
                _Pole.LVisitor = txtLVisitor.Text;
                _Pole.LVisit = ddlLVisit.SelectedIndex != 0 ? Int32.Parse(ddlLVisit.Items[ddlLVisit.SelectedIndex].ToString()) : Int32.MinValue;
                _Pole.Number = txtNumber.Text;
                if (!(bool)lblLocation.Tag)
                {
                    do
                    {
                        _DialogRes = MessageBox.Show("A GPS Solution is not available.\nDo you want to try again?", PPIConstants.K_AppName, MessageBoxButtons.YesNoCancel, MessageBoxIcon.None, MessageBoxDefaultButton.Button1);
                        if (_DialogRes == DialogResult.Yes)
                            RefreshLocation();
                    }
                    while (_DialogRes == DialogResult.Yes && !(bool)lblLocation.Tag);
                    switch (_DialogRes)
                    {
                        case DialogResult.Cancel:
                            _ErrMsg += "Pole addition aborted by user";
                            break;
                        case DialogResult.Yes:
                            _Pole.Longitude = m_Longitude;
                            _Pole.Latitude = m_Latitude;
                            _Pole.Altitude = m_Altitude;
                            _Pole.SatelliteCount = m_SatelliteCount;
                            _Pole.SatelliteTime = m_GPS.HasSolution ? m_GPS.NmeaGGA.SateliteTime : DateTime.Now.ToUniversalTime();
                            _Pole.SolutionAvailable = true;
                            break;
                        case DialogResult.No:
                            _Pole.Longitude = m_Visit.Longitude;
                            _Pole.Latitude = m_Visit.Latitude;
                            _Pole.Altitude = m_Visit.Altitude;
                            _Pole.SatelliteCount = m_Visit.SatelliteCount;
                            _Pole.SatelliteTime = m_GPS.HasSolution ? m_GPS.NmeaGGA.SateliteTime : DateTime.Now.ToUniversalTime();
                            _Pole.SolutionAvailable = false;
                            break;
                    }
                }
                else
                {
                    _Pole.Longitude = m_Longitude;
                    _Pole.Latitude = m_Latitude;
                    _Pole.Altitude = m_Altitude;
                    _Pole.SatelliteCount = m_SatelliteCount;
                    _Pole.SatelliteTime = m_GPS.HasSolution ? m_GPS.NmeaGGA.SateliteTime : DateTime.Now.ToUniversalTime();
                    _Pole.SolutionAvailable = true;
                }
                if (_ErrMsg != "")
                    MessageBox.Show(_ErrMsg, PPIConstants.K_AppName);
                else
                {
                    if (lstPoles.SelectedIndex > -1 && !alwaysAdd)
                        m_Poles[lstPoles.SelectedIndex] = _Pole;
                    else
                        m_Poles.Add(_Pole);
                    ShowList();
                    Clear();
                }
            }
        }
        private void ShowList()
        {
            PolesNumber = m_Poles.Count;
            lstPoles.Items.Clear();
            for (Int32 _I = 0; _I < m_Poles.Count; _I++)
                lstPoles.Items.Add("Pole " + (_I + 1).ToString() + (m_Poles[_I].SatelliteTime != DateTime.MinValue ? " (" + m_Poles[_I].SatelliteTime.AddMinutes(m_Settings.Timezone * 60).ToString("hh:mmtt") + ")" : ""));
            lstPoles.SelectedIndex = -1;
            lstPoles_SelectedIndexChanged(null, null);
        }
        private void cmdClear_Click(object sender, EventArgs e)
        {
            Clear();
        }
        private void Clear()
        {
            lstPoles.SelectedIndex = -1;
            ddlSpecies.SelectedIndex = 0;
            ddlClass.SelectedIndex = 0;
            ddlLength.SelectedIndex = 0;
            ddlYear.SelectedIndex = 0;
            ddlTop.SelectedIndex = m_TopIdList.IndexOf(m_Visit.TopTypeFk);
            ddlTreatment.SelectedIndex = 0;
            txtLVisitor.Text = "";
            ddlLVisit.SelectedIndex = 0;
            txtNumber.Text = "";
            RefreshLocation();
        }

        private void pbxRefresh_Click(object sender, EventArgs e)
        {
            RefreshLocation();
        }
        private void RefreshLocation()
        {
            if (m_GPS.HasSolution)
            {
                string stemp = "";
                m_Latitude = Utils.ConvertLatitudeToDecimal(m_GPS.NmeaGGA.Latitude, m_GPS.NmeaGGA.LatitudeHemisphere, ref stemp);
                m_Longitude = Utils.ConvertLongitudeToDecimal(m_GPS.NmeaGGA.Longitude, m_GPS.NmeaGGA.LongitudeHemisphere, ref stemp);
                m_Altitude = double.Parse(m_GPS.NmeaGGA.Altitude.ToString());
                m_SatelliteCount = m_GPS.NmeaGGA.SateliteCount;
                lblLocation.Tag = true;
                lblLocation.ForeColor = Color.Black;
                lblLocation.Text = m_Latitude.ToString("F6") + " / " + m_Longitude.ToString("F6") + " / " + m_Altitude.ToString("F2") + "ft";
            }
            else
            {
                m_Latitude = double.MinValue;
                m_Longitude = double.MinValue;
                m_Altitude = double.MinValue;
                m_SatelliteCount = Int32.MinValue;
                lblLocation.Tag = false;
                lblLocation.ForeColor = Color.Red;
                lblLocation.Text = "A GPS Solution is not available";
            }
        }

        private void mitDuplicatePole_Click(object sender, EventArgs e)
        {
            SavePole(true);
        }
        private void mitDeletePole_Click(object sender, EventArgs e)
        {
            bool _Delete;
            if (lstPoles.SelectedIndex > -1)
            {
                _Delete = true;
                if (m_Visit.Images != null)
                    foreach (EImage _Image in m_Visit.Images)
                        if (_Image.PoleFk == (_Image.PoleFkIsId ? m_Poles[lstPoles.SelectedIndex].PoleId : lstPoles.SelectedIndex))
                            _Delete = false;
                if (_Delete)
                {
                    if (m_Poles[lstPoles.SelectedIndex].PoleId != Int32.MinValue)
                        m_Visit.PolesToDelete.Add(m_Poles[lstPoles.SelectedIndex].PoleId);
                    m_Poles.RemoveAt(lstPoles.SelectedIndex);
                }
                else
                    MessageBox.Show("Unable to delete pole, it has photos assigned", PPIConstants.K_AppName);
            }
            ShowList();
            Clear();
        }
        private void mitAddPole_Click(object sender, EventArgs e)
        {
            if (lstPoles.SelectedIndex > -1)
                Clear();
            else
                SavePole();
        }

        private void txtLVisitor_GotFocus(object sender, EventArgs e)
        {
            iplKeyboard.Enabled = true;
        }
        private void txtLVisitor_LostFocus(object sender, EventArgs e)
        {
            iplKeyboard.Enabled = false;
        }
        private void txtNumber_GotFocus(object sender, EventArgs e)
        {
            iplKeyboard.Enabled = true;
        }
        private void txtNumber_LostFocus(object sender, EventArgs e)
        {
            iplKeyboard.Enabled = false;
        }

        protected override void tabMain_Click(object sender, EventArgs e)
        {
            ShowLoading();
            Application.DoEvents();
            m_Visit.Data = new EData();
            m_Visit.Data.Poles = m_Poles.ToArray();
            frmDataCollectionStructure _Form = new frmDataCollectionStructure();
            _Form.Visit = m_Visit;
            _Form.Settings = this.Settings;
            _Form.Show();
            this.Hide();
        }
        protected override void tabPhotos_Click(object sender, EventArgs e)
        {
            if (!m_TakePhotos)
            {
                MessageBox.Show("Cannot access the Photos form in 'No photos' mode", PPIConstants.K_AppName);
                tbcTabs.SelectedIndex = 1;
            }
            else
                lblRButton_Click(sender, e);
        }
    }
}
